/**
 * 该插件中包含了项目中的公共方法
 * 1.校验IP地址
 * 2.校验域名
 * 3.校验端口
 * 4.校验带回车的IP地址组
 *
 * 使用时：$tools为自定义的工具项
 * 作者：hanxu
 */
import moment from 'moment';
const common = {
  // 校验正整数
  // ^\d+$
  validateInteger(rule, value, callback) {
    if (/^\d+$/.test(value)) {
      callback();
    } else {
      callback(new Error('输入正整数'));
    }
  },
  // 校验IP地址
  validateAloneIP(rule, value, callback) {
    if (
      /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/.test(
        value,
      )
    ) {
      callback();
    } else {
      callback(new Error('输入正确的IP地址'));
    }
  },
  // 校验子网掩码
  validateMask(rule, value, callback) {
    if (
      /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/.test(
        value,
      )
    ) {
      callback();
    } else {
      callback(new Error('输入正确的子网掩码'));
    }
  },
  // 校验网关
  validateGateway(rule, value, callback) {
    if (
      /^192\.168(\.(\d|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))){2}$/.test(
        value,
      )
    ) {
      callback();
    } else {
      callback(new Error('输入正确的网关'));
    }
  },
  // 时间格式化
  formatDate(date, fmt) {
    // author: meizz
    const o = {
      'M+': date.getMonth() + 1, // 月份
      'd+': date.getDate(), // 日
      'h+': date.getHours(), // 小时
      'm+': date.getMinutes(), // 分
      's+': date.getSeconds(), // 秒
      'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
      S: date.getMilliseconds(), // 毫秒
    };
    if (/(y+)/.test(fmt))
      fmt = fmt.replace(
        RegExp.$1,
        (date.getFullYear() + '').substr(4 - RegExp.$1.length),
      );
    for (const k in o)
      if (new RegExp('(' + k + ')').test(fmt))
        fmt = fmt.replace(
          RegExp.$1,
          RegExp.$1.length == 1
            ? o[k]
            : ('00' + o[k]).substr(('' + o[k]).length),
        );
    return fmt;
  },
  // 导出文件
  exportFiled(data, name, type) {
    let url = window.URL.createObjectURL(new Blob([data]));

    if (type == 'csv') {
      url = window.URL.createObjectURL(new Blob(['\uFEFF' + data]));
    }

    const link = document.createElement('a');
    link.style.display = 'none';
    link.href = url;
    link.setAttribute('download', name);

    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  },
  // 校验IP
  validateIP(rule, value, callback) {
    if (value !== '') {
      const arr = value.split(/[(\r\n)\r\n]+/);
      const indexArr: any = [];
      arr.forEach((element, index) => {
        let boolen;
        let port;
        if (!element.includes('-') && !element.includes('/')) {
          boolen =
            /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/.test(
              element,
            );
          port =
            /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\:([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-5]{2}[0-3][0-5])$/.test(
              element,
            );
        } else if (element.includes('-')) {
          const lineArr = element.split('-');
          let boolen1;
          let lineNum = 0;
          lineArr.forEach((line, num) => {
            boolen1 =
              /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/.test(
                line,
              );
            if (!boolen1) {
              lineNum++;
            }
          });
          boolen = lineNum == 0;
        } else if (element.includes('/')) {
          const portArr = element.split('/');
          const portBoolen =
            /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/.test(
              portArr[0],
            );
          const portBoolean =
            parseInt(portArr[1]) > 15 &&
            parseInt(portArr[1]) < 33 &&
            /^[1-9]\d*$/.test(portArr[1]);
          if (portBoolen && portBoolean) {
            boolen = true;
            port = true;
          }
        }
        if (!boolen && !port) {
          indexArr.push(++index);
        }
      });
      if (indexArr.length == 0) {
        return callback();
      } else {
        return callback(
          new Error('第' + indexArr.join('、') + '行的IP地址有误'),
        );
      }
    } else if (rule.field == 'targets') {
      return callback(new Error('任务目标不能为空'));
    } else {
      return callback();
    }
  },
  // 校验端口
  validatePort(rule, value, callback) {
    if (value !== '') {
      const arr = value.split(/[(\r\n)\r\n]+/);
      const indexArr: any = [];
      let boolen;
      arr.forEach((element, index) => {
        if (element.includes('-')) {
          const lineArr = element.split('-');
          let lineNum = 0;
          let boolenLine;
          lineArr.forEach((line, num) => {
            boolenLine = parseInt(line) < 65535 && /^[1-9]\d*$/.test(line);
            if (!boolenLine) {
              lineNum++;
            }
          });
          boolen = lineNum == 0;
        } else {
          boolen = parseInt(element) < 65535 && /^[1-9]\d*$/.test(element);
        }

        if (!boolen) {
          indexArr.push(++index);
        }
      });
      if (indexArr.length == 0) {
        return callback();
      } else {
        return callback(
          new Error('第' + indexArr.join('、') + '行的端口地址有误'),
        );
      }
    } else {
      return callback();
    }
  },
  // 校验邮箱
  validateEmailAddr(rule, value, callback) {
    if (value !== '') {
      const arr = value.split(/[(\r\n)\r\n]+/);
      const indexArr: any = [];
      if (value == '') {
        return callback();
      } else {
        arr.forEach((element, index) => {
          const boolen =
            /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(element);
          if (!boolen) {
            indexArr.push(++index);
          }
        });
        if (indexArr.length == 0) {
          return callback();
        } else {
          return callback(
            new Error('第' + indexArr.join('、') + '行的邮箱有误'),
          );
        }
      }
    } else {
      return callback();
    }
  },
  // 校验并发线程
  validateMaxThreadNum(rule, value, callback) {
    if (value == '') {
      return callback(new Error('最大并发线程数不能为空'));
    } else if (/^[1-9][0-9]*$/.test(value) && JSON.parse(value) < 5001) {
      return callback();
    } else {
      return callback(new Error('输入格式不正确'));
    }
  },
  // 校验超时时长
  validateMaxTimeout(rule, value, callback) {
    if (value == '') {
      return callback(new Error('超时时长限制不能为空'));
    } else if (
      /^[1-9][0-9]*$/.test(value) &&
      JSON.parse(value) < 121 &&
      JSON.parse(value) > 5
    ) {
      return callback();
    } else {
      return callback(new Error('输入格式不正确'));
    }
  },
  // 判断字节长度
  StrLen(str) {
    let j = 0;
    const s = str;
    if (s == '') return j;
    for (let i = 0; i < s.length; i++) {
      if (s.substr(i, 1).charCodeAt(0) > 255) j = j + 2;
      else j++;
    }
    return j;
  },
  // 根据字节长度截取
  subStringByByte(str, length) {
    if (this.StrLen(str) <= length) {
      return str;
    } else {
      let len = 0;
      let i = 0;
      let subLength = length;
      while (len < length) {
        if (str.charCodeAt(i) > 256) {
          len += 2;
          subLength--;
        } else {
          len++;
        }
        i++;
      }
      return str.substring(0, subLength);
    }
  },
  // 设置当前页
  setPage(search, del) {
    const newP = (search.total - del) / search.pageSize;

    return Math.ceil(newP) > search.pageNumber
      ? search.pageNumber
      : Math.ceil(newP);
  },
  // 设置页面表格高度
  setTableHeight(clientHeight, moduleHeight) {
    const operation = 36;
    const mypagination = 60;
    const padding = 16 * 2;
    const margin = 16;

    const baseicHeight = operation + mypagination + padding + margin;

    const height = clientHeight - baseicHeight - moduleHeight;

    return height < 315 ? 315 : height;
  },
  // 根据页面高度调整页面显示条数
  setPageSize(height) {
    if (height > 875) {
      return 20;
    } else if (height > 635) {
      return 15;
    } else if (height > 395) {
      return 10;
    } else {
      return 5;
    }
  },
  // 数组去重
  unique(arr, prop) {
    const res = new Map();
    return arr.filter((arr) => !res.has(arr[prop]) && res.set(arr[prop], 1));
  },
  dateTimeClick(res) {
    const newDate = new Date();
    const updateTime = new Date(res.replace(/-/g, '/'));
    const dayDifference = newDate.getTime() - updateTime.getTime();
    // const time = parseInt(dayDifference / (1000 * 60 * 60 * 24))
    // const hours = parseInt(dayDifference / (1000 * 60 * 60))
    const time = Math.floor(dayDifference / (1000 * 60 * 60 * 24));
    const hours = Math.floor(dayDifference / (1000 * 60 * 60));
    const fiveDate = 5 * 1000 * 60 * 60 * 24;
    const oneDate = 1 * 1000 * 60 * 60 * 24;

    if (dayDifference >= oneDate && dayDifference <= fiveDate) {
      return time + '天前';
    }
    if (dayDifference <= oneDate) {
      return hours + '小时前';
    }
    return res;
  },
  // 计算时间差,返回：天数，小时，分钟，秒数,正计时
  dateTimeFlag(res) {
    const startTime = moment(res).valueOf(); // 开始时间
    const endTime = moment().valueOf(); // 结束时间
    const usedTime = endTime - startTime; // 相差的毫秒数
    const days = Math.floor(usedTime / (24 * 3600 * 1000)); // 计算出天数
    const leavel = usedTime % (24 * 3600 * 1000); // 计算天数后剩余的时间
    const hours = Math.floor(leavel / (3600 * 1000)); // 计算剩余的小时数
    const leavel2 = leavel % (3600 * 1000); // 计算剩余小时后剩余的毫秒数
    const minutes = Math.floor(leavel2 / (60 * 1000)); // 计算剩余的分钟数
    const leavel3 = leavel2 % (60 * 1000); // 计算剩余分钟后剩余的毫秒数
    const seconds = Math.floor(leavel3 / 1000); // 计算剩余的秒数
    return days + '天' + hours + '时' + minutes + '分' + seconds + '秒';
  },
  // 针对画布转换数据，type:save,数组转字符串, type:render,字符串转数组
  convertDataFormat(arr, type) {
    const newArr = arr.map((el) => {
      let value = el.value;
      if (
        el.componentConfig.componentType === 'select' &&
        el.componentConfig.multiple &&
        el.type === 'string'
      ) {
        if (type === 'render') {
          if (!(value instanceof Array)) {
            value = value.split(',');
          }
        }
        if (type === 'save') {
          if (value instanceof Array) {
            value = value.join(',');
          }
        }
      }
      return {
        ...el,
        value,
      };
    });
    return newArr;
  },
};

export default common;
